package com.dbflow5.database;

import ohos.data.rdb.*;

import java.util.function.Function;

/**
 * Description: Specifies the ohos default implementation of a database.
 */
public class OhosDatabase implements OhosDatabaseWrapper {
    RdbStore database;

    public OhosDatabase(RdbStore database){
        this.database = database;
    }

    @Override
    public void execSQL(String query) {
        rethrowDBFlowException(unused -> {
            database.executeSql(query);
            return null;
        });
    }

    @Override
    public boolean isInTransaction(){
        //return database.isInTransaction();
        return false;
    }

    @Override
    public void beginTransaction() {
        database.beginTransaction();
    }

    @Override
    public void setTransactionSuccessful() {
    }

    @Override
    public void endTransaction() {
        //database.endTransaction();
    }

    @Override
    public int getVersion() {
        return database.getVersion();
    }

    @Override
    public DatabaseStatement compileStatement(String rawQuery) {
        return rethrowDBFlowException (unused -> OhosDatabaseStatement.from(rawQuery, database.buildStatement(rawQuery), database));
    }

    @Override
    public FlowCursor rawQuery(String query, String[] selectionArgs) {
        return FlowCursor.from(database.querySql(query, selectionArgs));
    }

    @Override
    public long updateWithOnConflict(String tableName, ValuesBucket contentValues, String whereClause, String[] whereValues, RdbStore.ConflictResolution conflictAlgorithm) {
        RdbPredicates rdbPredicates = new RdbPredicates(tableName);
//        if(whereClause != null && whereValues != null){
//            for (int index = 0;index < whereColumn.length; index++){
//                rdbPredicates.equalTo(whereColumn[index], whereValues[index]);
//            }
//        }

        return rethrowDBFlowException(unused -> (long)database.updateWithConflictResolution(contentValues, rdbPredicates, conflictAlgorithm));
    }

    @Override
    public long insertWithOnConflict(String tableName, String nullColumnHack, ValuesBucket values, RdbStore.ConflictResolution sqLiteDatabaseAlgorithmInt) {
        return rethrowDBFlowException(unused -> database.insertWithConflictResolution(tableName, values, sqLiteDatabaseAlgorithmInt));
    }

    @Override
    public FlowCursor query(String tableName, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy){
        RdbPredicates rdbPredicates = new RdbPredicates(tableName);

//        if(selection != null && selectionArgs != null){
//            for (int index = 0; index < selection.length; index++){
//                rdbPredicates.equalTo(selection[index], selectionArgs[index]);
//            }
//        }
        rdbPredicates.orderByDesc(orderBy);
        rdbPredicates.groupBy(new String[]{groupBy});

        return rethrowDBFlowException(unused -> FlowCursor.from(database.query(rdbPredicates, columns)));
    }

    @Override
    public int delete(String tableName, String whereClause, String[] whereArgs) {
        RdbPredicates rdbPredicates = new RdbPredicates(tableName);
//        if(whereClause != null && whereArgs != null){
//            for (int index = 0; index < whereClause.length; index++){
//                rdbPredicates.equalTo(whereClause[index], whereArgs[index]);
//            }
//        }
        return rethrowDBFlowException (unused -> database.delete(rdbPredicates));
    }

    public static OhosDatabase from(RdbStore database) {
        return new OhosDatabase(database);
    }

    public static SQLiteException toDBFlowSQLiteException(SQLiteException e) {
        return new SQLiteException("A Database Error Occurred", e);
    }

    public static <T> T rethrowDBFlowException(Function<Void, T> fn) {
        try {
            return fn.apply(null);
        } catch (SQLiteException e) {
            throw toDBFlowSQLiteException(e);
        }catch (RdbException e1){
            System.out.println("Exception:--"+e1.getMessage());
            return null;
        }
    }
}

